package org.struts.util;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;

import org.struts.bean.XmlBean;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class StrutsConfig {
	
	
	
	private static final String STRUTS = "struts";
	private static final String ACTIONMAPPING = "actionMapping";
	private static final String ACTION = "action";
	private static final String NAME = "name";
	private static final String TYPE = "type";
	private static final String FORMCLASS = "formClass";
	private static final String FORMBEANS = "formBeans";
	private static final String FORMBEAN = "formBean";
	private static final String RESULT = "result";
	private static final String VALUE = "value";

	/**
	 * 读取struts-config配置文件
	 * 
	 * @param fileName
	 * @return
	 */
	public static Map<String, XmlBean> readXML(String  filename) {
		Map<String, XmlBean> map = null;
		// 1,得到文档文件
		Document document = null;
		try {
			document = getDocument(filename);
		} catch (Exception e) {
			throw new RuntimeException("解析配置文档struts-config失败!!!", e);
		}
		// 2,获得根目录

		Element root = (Element) document.getElementsByTagName(STRUTS).item(0);
		// 3,获得actionMapping节点
		Element actionMapping = getChildNode(root, ACTIONMAPPING).get(0);
		// 4,获得所有的action节点
		List<Element> actions = getChildNode(actionMapping, ACTION);
		// 5,构建map对象
		map = buildMap(root, actions);
		return map;
	}

	/**
	 * 构建map对象
	 * 
	 * @param root
	 * @param actions
	 * @return
	 */
	private static Map<String, XmlBean> buildMap(Element root,
			List<Element> actions) {
		Map<String, XmlBean> map = new HashMap<String, XmlBean>();
		XmlBean bean = null;
		for (Element action : actions) {
			bean = createBean(action, root);
			map.put(bean.getName(), bean);
		}
		return map;
	}

	/**
	 * 创建XmlBean对象
	 * 
	 * @param action2
	 * @return
	 */
	private static XmlBean createBean(Element action, Element root) {
		XmlBean bean = new XmlBean();
		bean.setName(action.getAttribute(NAME));
		bean.setType(action.getAttribute(TYPE));
		String formClass = getFormClass(bean.getName(), root);
		bean.setFormClass(formClass);
		Map<String, String> resultMap = getResultMap(action);
		bean.setResultMap(resultMap);
		return bean;
	}

	/**
	 * 获得action节点下面的result节点
	 * 
	 * @param action2
	 * @return
	 */
	private static Map<String, String> getResultMap(Element action) {
		Map<String, String> map = new HashMap<String, String>();
		List<Element> resultEles = getChildNode(action, RESULT);
		for(Element resultEle :resultEles){
			map.put(resultEle.getAttribute(NAME), resultEle.getAttribute(VALUE));
		}
		return map;
	}

	/**
	 * 获得同名下的formBean下的formClass
	 * 
	 * @param name
	 * @param root
	 * @return
	 */
	private static String getFormClass(String name, Element root) {
		String formClass = "";
		Element fbEles = getChildNode(root, FORMBEANS).get(0);
		List<Element> formBeans = getChildNode(fbEles, FORMBEAN);
		for (Element formBean : formBeans) {
			if (name.equals(formBean.getAttribute(NAME))) {
				formClass = formBean.getAttribute(FORMCLASS);
				break;
			}
		}
		return formClass;
	}

	/**
	 * 获得某节点下标签名为tagName的所有子节点
	 * 
	 * @param preEle
	 * @param tagName
	 * @return
	 */
	private static List<Element> getChildNode(Element preEle, String tagName) {
		List<Element> eles = new ArrayList<Element>();
		NodeList nodeList = preEle.getElementsByTagName(tagName);
		for (int i = 0; i < nodeList.getLength(); i++) {
			Element e = (Element) nodeList.item(i);
			eles.add(e);
		}
		return eles;
	}

	/**
	 * 获得文档对象
	 * 
	 * @param fileName
	 * @return
	 * @throws Exception
	 */
	private static Document getDocument(String filename ) throws Exception {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		FileInputStream file = new FileInputStream(filename);
		return dbf.newDocumentBuilder().parse(file);
	}

}
